<?php
if( IN_MANAGER_MODE != "true" ){
	die( '<strong>INCLUDE_ORDERING_ERROR</b><br /><br />Please use the MODx Content Manager instead of accessing this file directly.' );
}
/* !
** jSam - JavaScript Admin-Manager
** @version:
**   0.1
** @description:
**   Инструментарий разработчика MODx для настройки внешнего вида административной панели с помощью JavaScript-правил
**   Данный файл является служебной PHP-частью плагина
** @author:
**   Александр Кузнецов aka Regent(http://l-i-v-e.ru/)
** @license:
**   GNU General Public License version 3 - http://www.gnu.org/copyleft/gpl.html
** @home:
**   http://jsam-modx.net/
** @blog:
**   http://l-i-v-e.ru/
** @twitter:
**   http://twitter.com/vjRegent
*/
class JSAM{
	
	
	/******************************************************************************\
	****** Массив используемых и в последствии импортируемых в core.js данных ******
	****** Почти все данные устанавливаются при инициализации класса          ******
	\******************************************************************************/	
	/*
	** @name:
	**   data
	** @path:
	**   jSam -> data
	** @description:
	**   Основной массив данных
	** @type:
	**   Array
	*/
	var $data = array(
		
		/*
		** @name:
		**   version
		** @path:
		**   jSam -> data -> version
		** @description:
		**   Версия плагина jSam
		** @type:
		**   String
		*/
		'version' => '0.1',
		
		/*
		** @name:
		**   type
		** @path:
		**   jSam -> data -> type
		** @description:
		**   Тип фрейма
		** @type:
		**   String
		*/
		'type' => '',
		
		/*
		** @name:
		**   action
		** @path:
		**   jSam -> data -> action
		** @description:
		**   Номер REQUEST-действия
		** @type:
		**   Number
		*/
		'action' => 0,
		
		/*
		** @name:
		**   jSamAction
		** @path:
		**   jSam -> data -> jSamAction
		** @description:
		**   Номер jSam-REQUEST-действия
		** @type:
		**   Number
		*/
		'jSamAction' => 0,
		
		/*
		** @name:
		**   frame
		** @path:
		**   jSam -> data -> frame
		** @description:
		**   Явное имя подключаемого фрейма
		** @type:
		**   String
		*/
		'frame' => '',
		
		/*
		** @name:
		**   parentMap
		** @path:
		**   jSam -> data -> parentMap
		** @description:
		**   Ассоциативная карта родителей
		** @type:
		**   Array
		*/
		'parentMap' => array(),
		
		/*
		** @name:
		**   lang
		** @path:
		**   jSam -> data -> lang
		** @description:
		**   Язык административной панели управления
		** @type:
		**   String
		*/
		'lang' => 'russian',
		
		/*
		** @name:
		**   isStaticFrame
		** @path:
		**   jSam -> data -> isStaticFrame
		** @description:
		**   Данный фрейм является статичным, т. е. у него не меняется адрес. Таким фреймом может быть фрейм типа "menu"(Меню) или "tree"(Дерево ресурсов)
		** @type:
		**   Boolean
		*/
		'isStaticFrame' => false,
		
		/*
		** @name:
		**   isWorkingFrame
		** @path:
		**   jSam -> data -> isWorkingFrame
		** @description:
		**   Данный фрейм является рабочим, т. е. у него меняется адрес. Это правый нижний фрейм
		** @type:
		**   Boolean
		*/
		'isWorkingFrame' => false,
		
		/*
		** @name:
		**   isDocument
		** @path:
		**   jSam -> data -> isDocument
		** @description:
		**   Тип фрейма равен "document"
		** @type:
		**   Boolean
		*/
		'isDocument' => false,
		
		/*
		** @name:
		**   isNewDocument
		** @path:
		**   jSam -> data -> isNewDocument
		** @description:
		**   Тип фрейма равен "document" и фрейм является страницей создания нового ресурса
		** @type:
		**   Boolean
		*/
		'isNewDocument' => false,
		
		/*
		** @name:
		**   isWebLink
		** @path:
		**   jSam -> data -> isWebLink
		** @description:
		**   Тип фрейма равен "document" и фрейм является страницей создания/редактирования web-ссылки
		** @type:
		**   Boolean
		*/
		'isWebLink' => false,
		
		/*
		** @name:
		**   isNewWebLink
		** @path:
		**   jSam -> data -> isNewWebLink
		** @description:
		**   Тип фрейма равен "document" и фрейм является страницей создания web-ссылки
		** @type:
		**   Boolean
		*/
		'isNewWebLink' => false,
		
		/*
		** @name:
		**   isChunk
		** @path:
		**   jSam -> data -> isChunk
		** @description:
		**   Тип фрейма равен "chunk"
		** @type:
		**   Boolean
		*/
		'isChunk' => false,
		
		/*
		** @name:
		**   isNewChunk
		** @path:
		**   jSam -> data -> isNewChunk
		** @description:
		**   Тип фрейма равен "chunk" и фрейм является страницей создания чанка
		** @type:
		**   Boolean
		*/
		'isNewChunk' => false,
		
		/*
		** @name:
		**   document
		** @path:
		**   jSam -> data -> document
		** @description:
		**   Данные фрейма(те, которые запрашиваются и отправляются на сервер)
		** @type:
		**   Array
		*/
		'document' => array(
			'id' => 0,
			'parent' => 0
		),
		
		/*
		** @name:
		**   parent
		** @path:
		**   jSam -> data -> parent
		** @description:
		**   Информация о родителе ресурса
		** @type:
		**   Array
		*/
		'parent' => array(
			'id' => 0,
			'parent' => 0
		),
		
		/*
		** @name:
		**   parentTemplateVars
		** @path:
		**   jSam -> data -> parentTemplateVars
		** @description:
		**   Информация по TV-параметрам родителя ресурса
		** @type:
		**   Array
		*/
		'parentTemplateVars' => array(),
		
		/*
		** @name:
		**   extension
		** @path:
		**   jSam -> data -> extension
		** @description:
		**   Массив информации об расширениях jSam
		** @type:
		**   Array
		*/
		'extension' => array(),
		
		/*
		** @name:
		**   _lang
		** @path:
		**   jSam -> data -> _lang
		** @description:
		**   Массив русских фраз с переводом на язык административной панели
		** @type:
		**   Array
		*/
		'_lang' => array(),
		
		/*
		** @name:
		**   TV
		** @path:
		**   jSam -> data -> TV
		** @description:
		**   Массив информации о TV-параметрах вида { tv_name: tv_id }
		** @type:
		**   Array
		*/
		'TV' => array(),
		
		/*
		** @name:
		**   TVids
		** @path:
		**   jSam -> data -> TVids
		** @description:
		**   Массив информации о TV-параметрах вида { tv_id: tv_name }
		** @type:
		**   Array
		*/
		'TVids' => array(),
		
		/*
		** @name:
		**   url
		** @path:
		**   jSam -> data -> url
		** @description:
		**   Массив адресов
		** @type:
		**   Array
		*/
		'url' => array(),
		
		/*
		** @name:
		**   config
		** @path:
		**   jSam -> data -> config
		** @description:
		**   Информация об административной панели
		** @type:
		**   Array
		*/
		'config' => array()
		
	);
	
	
	/***********************************\
	****** Массив служебных данных ******
	\***********************************/
	/*
	** @name:
	**   service
	** @path:
	**   jSam -> service
	** @description:
	**   Массив служебных данных
	** @type:
	**   Array
	*/
	var $service = array(
		
		/*
		** @name:
		**   DOCTYPE
		** @path:
		**   jSam -> service -> DOCTYPE
		** @description:
		**   DOCTYPE фрейма
		** @type:
		**   String
		*/
		'DOCTYPE' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">',
		
		/*
		** @name:
		**   style
		** @path:
		**   jSam -> service -> style
		** @description:
		**   Строчка CSS-стилей, добавляемых в текущий фрейм
		** @type:
		**   String
		*/
		'style' => '',
		
		/*
		** @name:
		**   code
		** @path:
		**   jSam -> service -> code
		** @description:
		**   Код, выводимый по окончанию работы jSam
		** @type:
		**   String
		*/
		'code' => '',
		
		/*
		** @name:
		**   printCode
		** @path:
		**   jSam -> service -> printCode
		** @description:
		**   Печатать ли jSam код
		** @type:
		**   Boolean
		*/
		'printCode' => 1
		
	);
	
	
	/*
	** @name:
	**   options
	** @path:
	**   jSam -> options
	** @description:
	**   Стандартные опции
	** @type:
	**   Array
	*/
	var $options = array(
		
		// CSS-Стили для оверлея
		'overlayStyle' => 'background-color:#C4DCFB;',
		// Прозрачность оверлея
		'overlayOpacity' => 0.9,
		// Показывать оверлей или нет
		'overlayShow' => 1,
		// PHP код ручной настройки оверлея
		'overlaySetting' => "if( \$jSam_type == 'menu' ){\n\t\$jSam_options[ 'overlayStyle' ] = 'background-color:#456D4E;';\n}\nif( \$jSam_type == 'home' ){\n\t\$jSam_options[ 'overlayStyle' ] = 'background-color:#F7F7F7;';\n}",
		
		// Вариант подключения библиотеки jQuery
		//   1 - подключение с Google Code(Лучший вариант для сайта, находяшегося на настоящем web-сервере)
		//   0 - подключение из папки плагина(Лучший вариант для сайта, находяшегося на домашнем локальном сервере)
		'jquery' => 0,
		
		// Режим разработчика(создаёт некешируемые url`ы и т. д.)
		//   1 - включён
		//   0 - выключен
		'debug' => 0
		
	);
	
	
	/*******************************\
	|***** Управляющие функции *****|
	\*******************************/
	
	/*
	** @name:
	**   output
	** @path:
	**   jSam -> output
	** @description:
	**   Добавить код на печать от jSam
	** @param "$code":
	**   Строка HTML кода
	** @type:
	**   Function
	** @returns:
	**   null
	** @example:
	**   $jSam -> output( '<span class="jSam-other-code">Other code</span> - &larr; code' );
	*/
	function output( $code, $eol = true ){
		if( $eol ){
			$code .= PHP_EOL;
		}
		if( $this -> event -> name == 'OnManagerPageInit' ){
			$this -> service[ 'code' ] .= $code;
		}
		else{
			$this -> event -> output( $code );
		}
	}
	
	/*
	** @name:
	**   extend
	** @path:
	**   jSam -> extend
	** @description:
	**   Рекурсивное расширение одного массива другим
	**   Idea By Amund(http://www.php.net/manual/en/function.array-merge.php#95294)
	** @param "$a":
	**   Массив-основа для слияния
	** @param "$b":
	**   Массив, расширяющий основной массив
	** @type:
	**   Function
	** @returns:
	**   Array
	** @example:
	**   $jSam -> extend(
	**     array( 'num' => array( 1, 2 ), 'k' => 5 ),
	**     array( 'num' => array( 5, 2 ), 'low' => 855 )
	**   );
	*/
	function extend( $a, $b ){
		foreach( $b as $k => $v ){
			if( is_array( $v ) ){
				if( !isset( $a[ $k ] ) ){
					$a[ $k ] = $v;
				}
				else{
					$a[ $k ] = $this -> extend( $a[ $k ], $v );
				}
			}
			else{
				$a[ $k ] = $v;
			}
		}
		return $a;
	}
	
	/*
	** @name:
	**   event
	** @path:
	**   jSam -> event
	** @description:
	**   Искусственно добавить на событие выполнение PHP кода
	** @param "$eventName":
	**   Название события
	** @param "$code":
	**   Строка PHP кода
	** @param "$pluginName":
	**   Название искусственного плагина
	** @type:
	**   Function
	** @returns:
	**   String - название искусственного плагина
	** @example:
	**   $jSam -> event( 'OnDocFormPrerender', 'global $content; echo "<h2>" . $content[ "pagetitle" ] . "</h2>";' );
	*/
	function event( $eventName, $code, $pluginName = '' ){
		global $modx;
		$pluginName = !empty( $pluginName ) ? $pluginName : 'jSam-' . $eventName . '-' . $this -> pluginCount;
		$modx -> pluginCache[ $pluginName ] = $code;
		if( !array_key_exists( $eventName, $modx -> pluginEvent ) ){
			$modx -> pluginEvent[ $eventName ] = array();
		}
		$modx -> pluginEvent[ $eventName ][] = $pluginName;
		$this -> pluginCount++;
		return $pluginName;
	}
	var $pluginCount = 0;
	
	/*
	** @name:
	**   eventPath
	** @path:
	**   jSam -> eventPath
	** @description:
	**   Искусственно добавить на событие подключение файла
	** @param "$eventName":
	**   Название события
	** @param "$eventPath":
	**   Путь до подключаемого файла
	** @param "$pluginName":
	**   Название искусственного плагина
	** @type:
	**   Function
	** @returns:
	**   String - название искусственного плагина
	** @example:
	**   $jSam -> event( 'OnDocFormPrerender', 'path/to/file.php' );
	*/
	function eventPath( $eventName, $filePath, $pluginName = '' ){
		return $this -> event( $eventName, 'include( "' . $filePath . '" );', $pluginName );
	}
	
	/*
	** @name:
	**   addStyle
	** @path:
	**   jSam -> addStyle
	** @description:
	**   Добавить в фрейм CSS-стиль
	** @param "$str":
	**   String - CSS-стиль
	** @type:
	**   Function
	** @returns:
	**   null
	** @example:
	**   $jSam -> addStyle( '#myStyle{color:red;}' );
	*/
	function addStyle( $str = '', $eol = true ){
		if( $eol ){
			$str .= PHP_EOL;
		}
		$this -> service[ 'style' ] .= $str;
	}
	
	/*
	** @name:
	**   addScript
	** @path:
	**   jSam -> addScript
	** @description:
	**   Добавить в фрейм JavaScript код
	** @param "$code":
	**   String - JavaScript код
	** @type:
	**   Function
	** @returns:
	**   null
	** @example:
	**   $jSam -> addScript( "window.gloval_var_1 = 58;\nwindow.gloval_var_2 = 72;" );
	*/
	function addScript( $code = '', $eol = true ){
		if( $eol ){
			$code = PHP_EOL . $code . PHP_EOL;
		}
		$this -> output( "<script type=\"text/javascript\">" . $code . "</script>" );
	}
	
	/*
	** @name:
	**   addStyleUrl
	** @path:
	**   jSam -> addStyleUrl
	** @description:
	**   Прикрепить к документу файл CSS-стилей
	** @param "$url":
	**   String - путь к файлу CSS-стилей
	** @type:
	**   Function
	** @returns:
	**   null
	** @example:
	**   $jSam -> addStyleUrl( 'http://vl.vg/style8.css' );
	*/
	function addStyleUrl( $url ){
		$this -> service[ 'style' ] .= '@import url(' . $url . ( $this -> options[ 'debug' ] ? '?' . rand() : '' ) . ');' . PHP_EOL;
	}
	
	/*
	** @name:
	**   addScriptUrl
	** @path:
	**   jSam -> addScriptUrl
	** @description:
	**   Прикрепить к документу JavaScript файл
	** @param "$url":
	**   String - путь к JavaScript файлу
	** @type:
	**   Function
	** @returns:
	**   null
	** @example:
	**   $jSam -> addScriptUrl( 'http://vl.vg/script5.css' );
	*/
	function addScriptUrl( $url ){
		$this -> output( '<script type="text/javascript" src="' . $url . ( $this -> options[ 'debug' ] ? '?' . rand() : '' ) . '"></script>' );
	}
	
	/*
	** @name:
	**   extension
	** @path:
	**   jSam -> extension
	** @description:
	**   Добавить расширение в список расширений
	** @param "$extensionName":
	**   String - название расширения
	** @type:
	**   Function
	** @returns:
	**   Boolean - разрешение на подключение расширения
	** @example:
	**   $jSam -> extension( 'InTpl' );
	*/
	function extension( $extensionName ){
		if( !array_key_exists( $extensionName, $this -> data[ 'extension' ] ) ){
			$this -> data[ 'extension' ][ $extensionName ] = true;
		}
		return !!$this -> data[ 'extension' ][ $extensionName ];
	}
	
	
	/***********************\
	|***** Конструктор *****|
	\***********************/
	/*
	** @name:
	**   JSAM
	** @path:
	**   jSam -> JSAM
	** @description:
	**   Конструктор класса
	** @type:
	**   Function
	** @returns:
	**   null
	*/
	function JSAM(){
		
		global $modx, $manager_language, $_lang;
		
		// Variables
		$this -> event    = &$modx -> event;
		$data             = &$this -> data;
		$service          = &$this -> service;
		extract( $data, EXTR_REFS );
		$documentID       = &$document[ 'id' ];
		$parentID         = &$document[ 'parent' ];
		
		// Номер REQUEST-действия
		if( array_key_exists( 'action', $modx -> event -> params ) ){
			$action = $modx -> event -> params[ 'action' ];
		}
		
		// Явное название подключаемого фрейма
		if( isset( $_REQUEST[ 'f' ] ) ){
			$frame = preg_replace( '/[^a-z0-9]/i', '', $_REQUEST[ 'f' ] );
		}
		
		// Определение типа фрейма
		switch( $action ){
			
			// REQUEST действие №1 - Подключение PHP файла из папки manager/frames/
			// Возможные типы фрейма: "menu"(Меню) или "tree"(Дерево ресурсов)
			case 1:
				if( $frame == 'tree' || $frame == 'menu' ){
					$type = $frame;
					$isStaticFrame = true;
				}
				break;
				
			// REQUEST действие №2 - Подключение главной страницы
			// Тип фрейма: home
			case 2:
				$type = 'home';
				break;
			
			// REQUEST действие №4  -  Создание нового ресурса
			// REQUEST действие №72 -  Создание новой WEB-ссылки
			// REQUEST действие №27 -  Редактирование ресурса/WEB-ссылки
			// Тип фрейма: document
			case 4:
			case 72:
			case 27:
				$type = 'document';
				$isDocument = true;
				if( $action == 4 ){
					$isNewDocument = true;
				}
				if( $action == 72 ){
					$isNewWebLink = true;
				}
				break;
			
			// REQUEST действие №77 -  Создание нового чанка
			// REQUEST действие №78 -  Редактирование чанка
			// Тип фрейма: document
			case 77:
			case 78:
				$type = 'chunk';
				$isChunk = true;
				if( $action == 77 ){
					$isNewChunk = true;
				}
				break;
			
			// REQUEST действие №17 - Настройки
			// Тип фрейма: settings
			case 17:
				$type = 'settings';
				break;
			
			// REQUEST действие №1000 - jSam-действия
			// Тип фрейма: actions
			case 1000:
				global $action;
				$modx -> manager -> action = $action = 118;
				$type = 'actions';
				break;
			
			default:
				break;
		}
		
		// Языковые операции
		$lang = str_replace( '-utf8', '', str_replace( '-UTF8', '', $manager_language ) );
		if( $lang != 'russian' ){
			$__lang = $_lang;
			$_lang = array();
			include( 'lang/russian-UTF8.inc.php' );
			$russian_lang = $_lang;
			$_lang = $__lang;
			foreach( $russian_lang as $key => $value ){
				$_lang[ $value ] = array( $lang => $_lang[ $key ] );
			}
			unset( $__lang );
			unset( $russian_lang );
		}
		
		// Определение рабочего фрейма
		if( $type != '' && $isStaticFrame == false ){
			$isWorkingFrame = true;
		}
		
		// Создание url`ов
		$url[ 'base_path' ]                 = MODX_BASE_PATH;
		$url[ 'base_url' ]                  = MODX_BASE_URL;
		$url[ 'site_url' ]                  = MODX_SITE_URL;
		$url[ 'manager_path' ]              = MODX_MANAGER_PATH;
		$url[ 'manager_url' ]               = MODX_MANAGER_URL;
		$url[ 'assets_path' ]               = MODX_BASE_PATH . 'assets/';
		$url[ 'assets_url' ]                = MODX_BASE_URL . 'assets/';
		$url[ 'jsam_path' ]                 = $url[ 'assets_path' ] . 'plugins/jsam/';
		$url[ 'jsam_url' ]                  = $url[ 'assets_url' ] . 'plugins/jsam/';
		$url[ 'jsam_assets_path' ]          = $url[ 'jsam_path' ] . 'assets/';
		$url[ 'jsam_assets_url' ]           = $url[ 'jsam_url' ] . 'assets/';
		$url[ 'jsam_extensions_path' ]      = $url[ 'jsam_path' ] . 'extensions/';
		$url[ 'jsam_extensions_url' ]       = $url[ 'jsam_url' ] . 'extensions/';
		$url[ 'jsam_php_path' ]             = $url[ 'jsam_assets_path' ] . 'php/';
		$url[ 'jsam_php_url' ]              = $url[ 'jsam_assets_url' ] . 'php/';
		$url[ 'jsam_style_path' ]           = $url[ 'jsam_assets_path' ] . 'style/';
		$url[ 'jsam_style_url' ]            = $url[ 'jsam_assets_url' ] . 'style/';
		$url[ 'jsam_js_path' ]              = $url[ 'jsam_assets_path' ] . 'js/';
		$url[ 'jsam_js_url' ]               = $url[ 'jsam_assets_url' ] . 'js/';
		$url[ 'jsam_images_path' ]          = $url[ 'jsam_assets_path' ] . 'images/';
		$url[ 'jsam_images_url' ]           = $url[ 'jsam_assets_url' ] . 'images/';
		$url[ 'jsam_files_path' ]           = $url[ 'jsam_assets_path' ] . 'files/';
		$url[ 'jsam_files_url' ]            = $url[ 'jsam_assets_url' ] . 'files/';
		
		// Создание ассоциативной карты документов вида array( 'ID ресурса' => ID родителя ресурса )
		foreach( $modx -> documentMap as $val ){
			foreach( $val as $key => $val ){
				$parentMap[ $val ] = $key;
			}
		}
		
		// Получение ID ресурса из массива $_REQUEST
		if( isset( $_REQUEST[ 'id' ] ) ){
			$documentID = (int)$_GET[ 'id' ];
		}
		// Получение ID родителя ресурса из массива $_REQUEST
		if( isset( $_REQUEST[ 'pid' ] ) ){
			$parentID = (int)$_GET[ 'pid' ];
		}
		// Получение ID родителя ресурса из массива $data[ 'documentMap' ]
		elseif( $isDocument && $documentID != 0 ){
			$parentID = (int)$parentMap[ $documentID ];
		}
		
		// Считывание информации о родителе
		if( $isDocument && $parentID != 0 ){
			
			// Основные данные
			$parent = $modx -> db -> query( "SELECT * FROM " . $modx -> db -> config[ 'table_prefix' ] . "site_content WHERE `id` = " . $parentID );
			$parent = mysql_fetch_assoc( $parent );
			
			// TV-параметры
			$parentTemplateVars = $modx -> db -> query (
				"SELECT *, IF(tvc.value!='',tvc.value,tv.default_text) as value "
				. "FROM " . $modx -> getFullTableName( 'site_tmplvars' ) . " tv "
				. "INNER JOIN " . $modx -> getFullTableName( 'site_tmplvar_templates' ) . " tvtpl ON tvtpl.tmplvarid = tv.id "
				. "LEFT JOIN " . $modx -> getFullTableName( 'site_tmplvar_contentvalues' ). " tvc ON tvc.tmplvarid=tv.id AND tvc.contentid = '" . $parentID . "' "
				. "WHERE tv.id<>0 AND tvtpl.templateid = " . $parent[ 'template' ] . " "
				. "ORDER BY tv.rank ASC"
			);
			$parentTemplateVars = $modx -> db -> makeArray( $parentTemplateVars );
			
		}
		
		// Считывание информации о TV
		if( $isDocument ){
			$sql = 'SELECT `id`, `name` FROM ' . $modx -> getFullTableName( 'site_tmplvars' ) . ' ORDER BY `id`';
			$sql = $modx -> db -> query( $sql );
			$sql = $modx -> db -> makeArray( $sql );
			foreach( $sql as $tv ){
				$TV[ $tv[ 'name' ] ] = (int)$tv[ 'id' ];
				$TVids[ $tv[ 'id' ] ] = $tv[ 'name' ];
			}
			unset( $sql );
			unset( $tv );
		}
		
		// Данные менеджера
		$config = array(
			'language'               => $modx -> config[ 'manager_language' ],
			'role'                   => (int)$_SESSION[ 'mgrRole' ],
			'admin'                  => $_SESSION[ 'mgrShortname' ],
			'admin_email'            => $_SESSION[ 'mgrEmail' ],
			'site_email'             => $modx -> config[ 'emailsender' ],
			'which_editor'           => $modx -> config[ 'which_editor' ],
			'modx_version'           => $MODxVersion = $modx -> config[ 'settings_version' ],
			'default_template'       => (int)$modx -> config[ 'default_template' ],
			'datetime_format'        => $modx -> config[ 'datetime_format' ]
		);
		
	}
	
}

// JSAM должен инициализироваться только по наступлению событя OnManagerPageInit
if( $modx -> event -> name == 'OnManagerPageInit' ){
	
	// Инициализация объекта класса
	global $jSam;
	$jSam = new JSAM();
	
	// Добавление ссылки на jSam к объекту $modx
	$modx -> jSam = &$jSam;
	
	// Быстрые ссылки
	$jSam_data = &$jSam -> data;
	$jSam_type = $jSam_data[ 'type' ];
	$jSam_url  = $jSam_data[ 'url' ];
	
	// JSON
	if( !function_exists( 'json_encode' ) ){
		if( !class_exists( 'Services_JSON' ) ){
			include( $url[ 'jsam_php_path' ] . 'json.php' );
		}
		$jSam -> Services_JSON = new Services_JSON();
		function json_encode( $value ){
			global $jSam;
			return $jSam -> Services_JSON -> encode( $value );
		}
		function json_decode( $value ){
			global $jSam;
			return $jSam -> Services_JSON -> decode( $value );
		}
	}
	
	// Если тип фрейма поддерживается, то происходит подключение jSam
	if( $jSam_type != '' ){
		
		// Variables
		$jSam_options = &$jSam -> options;
		$jSam_service = &$jSam -> service;
		extract( $jSam_url, EXTR_SKIP );
		
		$modx -> invokeEvent( 'jSamStarted' );
		
		// Импорт пользовательских опций
		if( isset( $jSamOptions ) && is_array( $jSamOptions ) ){
			$jSam_options = $jSam -> extend( $jSam_options, $jSamOptions );
			unset( $jSamOptions );
		}
		
		// Style
		$jSam -> addStyleUrl( $jsam_style_url . 'jquery-ui/base.css' );
		$jSam -> addStyleUrl( $jsam_style_url . 'jquery-ui/start/jquery-ui-1.8.1.custom.css' );
		$jSam -> addStyleUrl( $jsam_style_url . 'colorpicker/colorpicker.css' );
		
		// Постройка оверлея jSam-preloader
		if( array_key_exists( 'overlaySetting', $jSam_options ) && is_string( $jSam_options[ 'overlaySetting' ] ) ){
			@eval( $jSam_options[ 'overlaySetting' ] );
		}
		if( $jSam_options[ 'overlayShow' ] ){
			$jSam -> addStyle( '#jSam-preLoader{opacity:' . $jSam_options[ 'overlayOpacity' ] . ';' . $jSam_options[ 'overlayStyle' ] . '}' );
			$jSam -> addStyle( '#preLoader{display:none;}' );
			$jSam -> output( '<div id="jSam-preLoader"></div><link rel="stylesheet" type="text/css" href="' . $jsam_style_url . 'base.css" />' );
		}
		
		// Подключение библиотеки jQuery
		$jSam -> addScriptUrl( $jSam_options[ 'jquery' ] ? 'http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js' : $jsam_js_url . 'jquery.min.js' );
		
		// Подключение дополнительных скриптов
		$jSam -> addScriptUrl( $jsam_js_url . 'scripts.js' );
		
		// Данные
		$jSam -> addScript( 'window.jSamData = {};' );
		
		// Подключение jSam JavaScript Core
		$jSam -> addScriptUrl( $jsam_js_url . 'core.' . ( $jSam_options[ 'debug' ] ? '' : 'min.' ) . 'js' );
		
		// Подключение правил
		$rules = @file_get_contents( $jsam_path . 'rules.js' );
		if( !empty( $rules ) ){
			$jSam -> addScript( $rules );
		}
		unset( $rules );
		
		// Подключение расширений
		if( $handle = opendir( $jsam_extensions_path ) ){
			$ignore_first_chars = array( '.', '_', '!' );
			$modx -> invokeEvent( 'jSamLoadExtensions' );
			while( false !== ( $extensionFileName = readdir( $handle ) ) ){
				if( !in_array( substr( $extensionFileName, 0, 1 ), $ignore_first_chars ) && $extensionFileName != '..' ){
					$extensionFilePath    = $jsam_extensions_path . $extensionFileName;
					$extensionFileUrl     = $jsam_extensions_url  . $extensionFileName;
					$extensionIsInclude   = preg_match( '/^(.+)\.inc\.(php|js|css)$/', $extensionFileName, $extensionFileInfo );
					if( $extensionIsInclude && $jSam -> extension( $extensionFileInfo[ 1 ] ) ){
						unset( $extensionIsInclude );
						$result = $modx -> invokeEvent(
							'jSamExtension',
							array(
								'fileName'    => $extensionFileName,
								'filePath'    => $extensionFilePath,
								'fileUrl'     => $extensionFileUrl,
								'fileInfo'    => $extensionFileInfo
							)
						);
						$result = is_array( $result ) ? !in_array( false, $result ) : true;
						if( $result ){
							unset( $result );
							switch( $extensionFileInfo[ 2 ] ){
								case 'php':
									include( $extensionFilePath );
									break;
								case 'js':
									$jSam -> addScriptUrl( $extensionFileUrl );
									break;
								case 'css':
									$jSam -> addStyleUrl( $extensionFileUrl );
									break;
								default:
									break;
							}
						}
					}
				}
			}
			closedir( $handle );
			unset( $ignore_first_chars );
			unset( $extensionFileName );
			unset( $extensionFilePath );
			unset( $extensionFileUrl );
			unset( $extensionFileInfo );
			unset( $extensionIsInclude );
			unset( $result );
			
		}
		
		// Вызов события jSamCreated
		$modx -> invokeEvent( 'jSamCreated' );
		
	}
	
	// Стили
	if( strlen( $jSam_service[ 'style' ] ) ){
		$jSam -> output( "<style type='text/css'>" . PHP_EOL . $jSam_service[ 'style' ] . "</style>" );
	}
	
	if( $jSam_type == 'actions' ){
		ob_start();
		include( 'actions.php' );
		$actionsResult = ob_get_clean();
	}
	
	// Печать конечного кода
	if( $jSam_service[ 'printCode' ] && strlen( $jSam_service[ 'code' ] ) ){
		
		$jSam_service[ 'code' ] = str_replace( 'jSamData = {}', 'jSamData = ' . json_encode( $jSam_data ), $jSam_service[ 'code' ] );
		
		// Вызов события jSamOutputCode
		$modx -> invokeEvent( 'jSamOutputCode', array( 'code' => &$jSam_service[ 'code' ] ) );
		
		echo $jSam_service[ 'DOCTYPE' ]
			. "\n<!--~~--~~--~~--~~--~~--~~--~~--~~--~~--~~            jSam Code Start           ~~--~~--~~--~~--~~--~~--~~--~~--~~--~~-->"
			. "\n<div id='jSam-box' class='jSam-frame-" . ( $jSam_data[ 'isWorkingFrame' ] ? 'Working' : 'Static' ) . " jSam-frame-" . $jSam_type . "'>"
			. "\n" . $jSam_service[ 'code' ]
			. "</div>"
			. "\n<!--~~--~~--~~--~~--~~--~~--~~--~~--~~--~~            jSam Code  End            ~~--~~--~~--~~--~~--~~--~~--~~--~~--~~-->"
			. "\n";
	}
	
	if( isset( $actionsResult ) ){
		echo $actionsResult;
		unset( $actionsResult );
	}
}
?>